#include <streambuf>
#include"LargeNumberPtr.h"
#include"LargeNumber.h"

LargeNumberPtr::LargeNumberPtr() : ptr_(0), copy_counter_(0) {}

LargeNumberPtr::LargeNumberPtr(LargeNumber * ptr) : ptr_(ptr), copy_counter_(new int(1)) {}

LargeNumberPtr::~LargeNumberPtr() {
    if((*copy_counter_) == 1) {
        delete ptr_;
        delete copy_counter_;
    } else {
        --(*copy_counter_);
    }
}

LargeNumberPtr::LargeNumberPtr(LargeNumberPtr const & copy): ptr_(copy.ptr_) {
    copy_counter_ = copy.copy_counter_;
    ++(*copy_counter_);
}

LargeNumber & LargeNumberPtr::operator = (LargeNumberPtr const & right) {
    if(ptr_ != right.ptr_) {
        LargeNumberPtr(right).swap(*this);
        ++(*copy_counter_);
    }
    return *ptr_;
}

void LargeNumberPtr::operator = (LargeNumber * right) {
    if(ptr_ != right) {
        LargeNumberPtr(right).swap(*this);
    }
}

LargeNumber * LargeNumberPtr::operator -> () const {
    return ptr_;
}

LargeNumber & LargeNumberPtr::operator * () const {
    return *ptr_;
}

bool LargeNumberPtr::operator !=(LargeNumberPtr const & right) const {
    return (ptr_ != right.ptr_);
}

bool LargeNumberPtr::operator ==(LargeNumberPtr const & right) const {
    return (ptr_ == right.ptr_);
}

bool LargeNumberPtr::operator <(LargeNumberPtr const & right) const {
    return (ptr_ < right.ptr_);
}

bool LargeNumberPtr::operator >(LargeNumberPtr const & right) const {
    return (ptr_ > right.ptr_);
}

bool LargeNumberPtr::operator <=(LargeNumberPtr const & right) const {
    return (ptr_ <= right.ptr_);
}

bool LargeNumberPtr::operator >=(LargeNumberPtr const & right) const {
    return (ptr_ >= right.ptr_);
}

bool LargeNumberPtr::operator ==(LargeNumber * right) const {
    return (ptr_ == right);
}

LargeNumber * LargeNumberPtr::getPointer() const {
    return ptr_;
}

void LargeNumberPtr::swap(LargeNumberPtr & right) {
    std::swap(ptr_, right.ptr_);
    std::swap(copy_counter_, right.copy_counter_);
}